﻿@page "/"
@using System.Reflection

<MudLayout>
    <MudAppBar Elevation="0">
        <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="DocsDrawerToggle" />
        <MudText Typo="Typo.h6">@selectedType?.Name</MudText>
        <MudSpacer />
        <MudAutocomplete @ref="autocomplete" T="Type" Placeholder="Search" SearchFunc="Search" Variant="Variant.Outlined" ValueChanged="OnSearchResult" Class="docs-search-bar" AdornmentIcon="@Icons.Material.Filled.Search">
            <ItemTemplate Context="result">
                <MudText>@result.Name</MudText> <MudText Typo="Typo.body2">@getDescription(result)</MudText>
            </ItemTemplate>
        </MudAutocomplete>
        <MudSpacer />
    </MudAppBar>
    <MudDrawer Open="@drawerOpen" DisableOverlay="true" Variant="DrawerVariant.Responsive" ClipMode="DrawerClipMode.Always" Breakpoint="Breakpoint.Sm">
        <MudDrawerHeader>
            <MudText Typo="Typo.h6">TestComponents</MudText>
        </MudDrawerHeader>
        <MudList>
            @foreach (var type in availableComponentTypes)
            {
                <MudListItem OnClick="@(() => selectedType = type)" @key="type.Name">@type.Name</MudListItem>
            }
        </MudList>
    </MudDrawer>
    <MudMainContent Class="mt-4">

        <MudText Style="padding-left: 24px; margin-left: 24px;">
            @getDescription(selectedType)
        </MudText>
        <MudPaper Elevation="5" Style="padding: 24px; margin: 24px;">
            @if (@selectedType == null)
            {
                <span>Select a component</span>
            }
            else
            {
                @* Prevent double popovers! *@
                <CascadingValue Name="UsePopoverProvider" Value="false"  IsFixed="true">
                    @TestComponent()
                </CascadingValue>
            }
        </MudPaper>

    </MudMainContent>
</MudLayout>
<style>
    .docs-search-bar .mud-input{height:42px;}
    .docs-search-bar.mud-input-control{background-color:rgba(255,255,255,.15);margin-bottom:5px;height:42px;border-radius:var(--mud-default-borderradius);}
    .docs-search-bar.mud-input-control .mud-input-root,.docs-search-bar.mud-input-control .mud-icon-default{color:#fafafa;}
    .docs-search-bar .mud-input.mud-input-outlined .mud-input-outlined-border{border:none;border-radius:var(--mud-default-borderradius);}
</style>

@code {
    bool drawerOpen = true;
    Type selectedType = null;
    Type[] availableComponentTypes = new Type[0];
    MudAutocomplete<Type> autocomplete;

    void DocsDrawerToggle()
    {
        drawerOpen = !drawerOpen;
    }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        availableComponentTypes = getTestComponenTypes().ToArray();
    }

    RenderFragment TestComponent() => builder =>
    {
        builder.OpenComponent(0, selectedType);
        //builder.AddAttribute(1, "Title", "Some title");
        builder.CloseComponent();
    };

    IEnumerable<Type> getTestComponenTypes()
    {
        foreach (var type in typeof(Program).Assembly.GetTypes().OrderBy(x => x.Name))
        {
            if (!type.Name.Contains("Test"))
                continue;
            if (type.Name.StartsWith("<"))
                continue;
            if (!type.GetInterfaces().Contains(typeof(IComponent)))
                continue;
            yield return type;
        }
        //foreach (var type in typeof(MudBlazor.Docs.Components.DocsPage).Assembly.GetTypes())
        //{
        //    if (!type.Name.EndsWith("Example"))
        //        continue;
        //    if (type.Name.StartsWith("<"))
        //        continue;
        //    yield return type;
        //}
    }

    private string getDescription(Type type)
    {
        if (type == null)
            return "";
        try
        {
            var field = type.GetField("__description__", BindingFlags.Public | BindingFlags.Static | BindingFlags.GetField);
            return (string)field.GetValue(null);
        }
        catch (Exception)
        {
            return "public static string __description__ = \"...\"; not found in this component.";
        }
    }

    private Task<IEnumerable<Type>> Search(string text)
    {
        if (string.IsNullOrWhiteSpace(text))
        {
            // the user just clicked the autocomplete open, show the most popular pages as search result according to our analytics data
            // ordered by popularity
            return Task.FromResult<IEnumerable<Type>>(new Type[0]);
        }
        var lowerText = text.ToLowerInvariant();
        return Task.FromResult<IEnumerable<Type>>(
            availableComponentTypes.Where(type => type.Name.ToLowerInvariant().StartsWith(lowerText))
        );
    }

    private async void OnSearchResult(Type entry)
    {
        selectedType = entry;
        await Task.Delay(1000);
        await autocomplete.Clear();
    }
}